package org.koyad.portal.servlet;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.koyad.portal.api.BaseAction;
import org.koyad.portal.constants.FrameworkConstants;
import org.koyad.portal.context.PistonContext;
import org.koyad.portal.exceptions.FrameworkException;
import org.koyad.portal.filters.PageUtils;
import org.koyad.portal.tags.ViewRoot;
import org.koyad.portal.utils.LogUtils;

/**
 * Acts as a front controller for normal requests.
 * 
 * @author koyad
 */
@SuppressWarnings("serial")
@WebServlet (
		name = "PistonServlet", 
		urlPatterns = { 
			"/" + FrameworkConstants.PISTON_PORTAL_PAGES + "/*", 
			"*.page",
			"/" + FrameworkConstants.PISTON_FWK 
		}
)
public class PistonServlet extends HttpServlet {

	private static final LogUtils LOGGER = LogUtils.getLogger(PistonServlet.class);

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		LOGGER.startMethod("doGet");

		try {
			ViewRoot viewRoot = PistonContext.getContext().getViewRoot();
			if(null != viewRoot) {
				try {
					viewRoot.render();
				} catch (Exception ex) {
					LOGGER.logException(ex);
					PistonContext.getContext().resetViewRoot();
					PageUtils.include("/Error.html", req, resp);
				}
				if(viewRoot.getErrors().size() > 0) {
					viewRoot.resetErrors();
				} 
			} else {
				PageUtils.include("/Error.html", req, resp);
			}
		} catch (FrameworkException e) {
			handleException(e);
		}

		LOGGER.endMethod("doGet");

	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		LOGGER.startMethod("doPost");
		
		ViewRoot viewRoot = PistonContext.getContext().getViewRoot();
		viewRoot.validate();
		
		if(viewRoot.validationFailed()) {
			doGet(req, resp);
		} else {
		
			String actionName = req.getParameter(FrameworkConstants.PISTON_FWK_ACTION);
			PistonContext pistonCtx = PistonContext.getContext();
			Map<String, String> actions = (Map<String, String>) pistonCtx.getApplication().getAttribute(FrameworkConstants.PISTON_ACTIONS);
			String action = actions.get(actionName);
			
			try {
				Class actionClass = Class.forName(action);
				BaseAction bAction = (BaseAction)actionClass.newInstance();

				PistonContext.getContext().getViewRoot().setCurrentTile();
				bAction.execute();
				PistonContext.getContext().getViewRoot().resetCurrentTile();
			} catch (Exception e) {
				handleException(e);
				PageUtils.include("/Error.html", req, resp);
			}
			
			//if action is not requesting redirect then continue with normal rendering
			if(resp.getStatus() != HttpServletResponse.SC_FOUND) {
				doGet(req, resp);
			}
		}
		
		LOGGER.endMethod("doPost");
	}
	
	private void handleException(Exception e) throws ServletException, IOException {
		LOGGER.logException(e);
	}
	
}
